#ifndef __OS_H__
#define __OS_H__

#ifdef __cplusplus
extern "C"
{
#endif

struct _SEMAPHOR;
typedef struct _SEMAPHOR   SEMAPHOR;
struct _MUTEX;
typedef struct _MUTEX    MUTEX;
struct _THREAD;
typedef struct _THREAD   THREAD;

typedef int32_t (*ThreadProc)(THREAD *, void *);

struct _SEMAPHOR
{
#ifdef ECOS
    cyg_sem_t               semaphore_t;
#elif defined(LINUX)
    sem_t                   semaphore_t;
#endif
};

struct _MUTEX
{
#ifdef ECOS
    cyg_mutex_t             hMutex;
#elif defined(LINUX)
    pthread_mutex_t         hMutex;
#endif
};

struct _THREAD
{
    ThreadProc            pFun;
    void*                   pUserData;
    
#ifdef ECOS
    int8_t*                     pStack;
    cyg_handle_t            hThread;
    cyg_thread              ThreadObj;
#elif defined(LINUX)
    pthread_t               hThread;
    SEMAPHOR                SuspendEvent;
#endif
};

bool32_t  SemaphoreInit(SEMAPHOR *, int32_t);
bool32_t  SemaphoreADD(SEMAPHOR *);
bool32_t  SemaphoreWait(SEMAPHOR *);
bool32_t  EventDestroy(SEMAPHOR *);

bool32_t  MutexCreate(MUTEX *);
bool32_t  MutexLock(MUTEX *);
bool32_t  MutexUnlock(MUTEX *);
bool32_t  ReleaseMutex(MUTEX *);

THREAD *ThreadCreate(ThreadProc, void *);
bool32_t  ThreadSetPriority(THREAD *, int32_t);
bool32_t  ThreadSuspend(THREAD *);
bool32_t  ThreadResume(THREAD *);
bool32_t  ThreadDestroy(THREAD *);

uint32_t  GetCurrentThreadId(void);

void Sleep(uint32_t);
uint64_t GetTime(void);

static inline void *Malloc(int32_t nSize)
{
    return malloc(nSize);
}

static inline void *Calloc(int32_t nNum, int32_t nSize)
{
    return calloc(nNum, nSize);
}

static inline void *Realloc(void *pAddr, int32_t nOldSize, int32_t nNewSize)
{
    return realloc(pAddr, nNewSize);
}

static inline void Free(void *pAddr)
{
    free (pAddr);
}

static inline int32_t StrCaseCmp(const int8_t *s1, const int8_t *s2)
{
    return strcasecmp (s1, s2);
}

void DebugPrint(const int8_t *, ...);

#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif
